package queue.impl;

import queue.Queue;

import java.util.NoSuchElementException;

/**
 * 基于整型循环队列
 */
public class LoopQueue implements Queue<Integer> {
    //长度固定的数组
    private Integer[] data;
    //队首元素
    private int head;
    //指向队尾元素的下一个索引
    private int tail;

    /**
     * 保存最大元素个数size个，那么数组长度就要再加1
     * @param size
     */
    public LoopQueue(int size){
        //因为循环队列需要浪费一个空间来判断队列是否已满
        data=new Integer[size+1];
    }


    @Override
    public void offer(Integer val) {
        if (isFull()){
            throw new ArrayIndexOutOfBoundsException("LoopQueue is full!cannot offer");
        }
        data[tail]=val;
        tail=(tail+1)% data.length;
    }

    @Override
    public Integer poll() {
       if (isEmptty()){
           throw new NoSuchElementException("LoopQueue is empty!cannot poll!");
       }
       //移动队首元素
        Integer val=data[head];
       head=(head+1)% data.length;
       return val;
    }

    @Override
    public Integer peek() {
        if (isEmptty()){
            throw new NoSuchElementException("LoopQueue is empty!cannot peek!");
        }
        return data[head];
    }

    /**
     * 判断数组是否为空
     * @return
     */
    @Override
    public boolean isEmptty() {
        return head==tail;
    }

    /**
     * 判断队列是否已满
     * @return
     */
    public boolean isFull(){
        return (tail+1)% data.length==head;
    }

    /**
     * 注意判断最后一个元素的索引
     * 当tail==0时，就是data.length-1
     * 当tail在其他位置时，就是tail-1
     * 此时使用三目运算符来实现
     * @return
     */
    @Override
    public String toString() {
        StringBuilder sb=new StringBuilder();
        sb.append("front [");
        int lastIndex=tail==0? data.length -1:tail-1;
        for (int i = head; i < tail;) {
            sb.append(data[i]);

            if(i !=lastIndex){
                sb.append("， ");
            }
            i=(i+1)% data.length;
        }
        sb.append("] tail");
        return sb.toString();
    }
}
